package com.triones.api.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.triones.api.entity.*;
import com.triones.api.entity.bo.NoticeBO;
import com.triones.api.entity.interlace.dto.InterlaceMemberDO;
import com.triones.api.entity.interlace.dto.InterlaceNoticeDO;
import com.triones.api.entity.interlace.dto.InterlaceNoticeMemberDO;
import com.triones.api.entity.interlace.dto.InterlaceNoticeSceneDO;
import com.triones.api.entity.interlace.vo.InterlaceNoticeSceneVO;
import com.triones.api.entity.param.CustomNoticeMemberParams;
import com.triones.api.entity.param.NoticeParams;
import com.triones.api.entity.vo.*;
import com.triones.api.mapper.*;
import com.triones.api.mapper.interlace.InterlaceMemberMapper;
import com.triones.api.mapper.interlace.InterlaceNoticeMapper;
import com.triones.api.mapper.interlace.InterlaceNoticeMemberMapper;
import com.triones.api.mapper.interlace.InterlaceNoticeSceneMapper;
import com.triones.api.service.NoticeService;
import com.triones.api.service.interlace.PushService;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 通知 -业务实现
 */
@Service
@RequiredArgsConstructor
public class NoticeServiceImpl implements NoticeService {

    private final InterlaceNoticeSceneMapper interlaceNoticeSceneMapper;

    private final InterlaceNoticeMapper interlaceNoticeMapper;

    private final InterlaceNoticeMemberMapper interlaceNoticeMemberMapper;

    private final PushService pushService;

    private final InterlaceMemberMapper interlaceMemberMapper;

    @Override
    public TableDataInfo<CustomNoticeVO> pageList(InterlaceNoticeDO dto, PageQuery pageQuery) {
        Map<String, Object> params = dto.getParams();
        QueryWrapper<Object> wrapper = Wrappers.query();
        wrapper.eq("tin.sys_del", 0);
        wrapper.and(StringUtils.isNotBlank(dto.getEnTitle()),
            wq -> wq.like("tin.zh_title", dto.getEnTitle()).or()
                .like("tin.en_title", dto.getEnTitle()).or()
                .like("tin.ja_title", dto.getEnTitle()).or()
                .like("tin.zh_content", dto.getEnTitle()).or()
                .like("tin.en_content", dto.getEnTitle()).or()
                .like("tin.ja_content", dto.getEnTitle()).or()
        );
        wrapper.eq(StringUtils.isNotBlank(dto.getNtfObjRange()), "tin.ntf_obj_range", dto.getNtfObjRange());
        wrapper.eq(StringUtils.isNotBlank(dto.getSceneType()), "tin.scene_type", dto.getSceneType());
        wrapper.between(params.get("beginTime") != null && params.get("endTime") != null,
            "tin.create_time", params.get("beginTime"), params.get("endTime"));
        wrapper.orderByDesc("tin.create_time");
        Page<CustomNoticeVO> result = interlaceNoticeMapper.selectPageList(pageQuery.build(), wrapper);
        return TableDataInfo.build(result);
    }

    @Override
    public boolean remove(Long id) {
        InterlaceNoticeDO interlaceNoticeDO = interlaceNoticeMapper.selectById(id);
        if (interlaceNoticeDO == null) {
            throw new ServiceException("通知不存在");
        }
        interlaceNoticeDO.setSysDel("1");
        /**
         * 删除用户通知关联表
         */
        interlaceNoticeMemberMapper.update(null, new LambdaUpdateWrapper<InterlaceNoticeMemberDO>()
            .set(InterlaceNoticeMemberDO::getDel, "1")
            .eq(InterlaceNoticeMemberDO::getNid, id));
        return interlaceNoticeMapper.updateById(interlaceNoticeDO) > 0;
    }

    @Override
    public TableDataInfo<InterlaceNoticeSceneVO> noticeSceneList(String keyword, PageQuery pageQuery) {
        LambdaQueryWrapper<InterlaceNoticeSceneDO> lqw = new LambdaQueryWrapper<InterlaceNoticeSceneDO>();
        lqw.like(StringUtils.isNotBlank(keyword), InterlaceNoticeSceneDO::getName, keyword).or()
            .like(StringUtils.isNotBlank(keyword), InterlaceNoticeSceneDO::getType, keyword);
        lqw.eq(InterlaceNoticeSceneDO::getDel, "0");
        lqw.orderByDesc(InterlaceNoticeSceneDO::getCreateTime);
        Page<InterlaceNoticeSceneVO> result = interlaceNoticeSceneMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    @Override
    public boolean checkNoticeSceneName(InterlaceNoticeSceneDO noticeSceneDO) {
        boolean exist = interlaceNoticeSceneMapper.exists(new LambdaQueryWrapper<InterlaceNoticeSceneDO>()
            .eq(InterlaceNoticeSceneDO::getName, noticeSceneDO.getName())
            .eq(InterlaceNoticeSceneDO::getType, noticeSceneDO.getType())
            .eq(InterlaceNoticeSceneDO::getDel, "0")
            .ne(ObjectUtil.isNotNull(noticeSceneDO.getId()), InterlaceNoticeSceneDO::getId, noticeSceneDO.getId()));
        return !exist;
    }

    @Override
    public boolean addNoticeScene(InterlaceNoticeSceneDO noticeSceneDO) {
        noticeSceneDO.setCreateTime(System.currentTimeMillis());
        return interlaceNoticeSceneMapper.insert(noticeSceneDO) > 0;
    }

    @Override
    public boolean editNoticeScene(InterlaceNoticeSceneDO noticeSceneDO) {
        return interlaceNoticeSceneMapper.updateById(noticeSceneDO) > 0;
    }

    @Override
    public boolean removeNoticeScene(Long id) {
        InterlaceNoticeSceneDO interlaceNoticeSceneDO = interlaceNoticeSceneMapper.selectById(id);
        if (interlaceNoticeSceneDO == null) {
            throw new ServiceException("通知场景不存在");
        }
        interlaceNoticeSceneDO.setDel("1");
        return interlaceNoticeSceneMapper.updateById(interlaceNoticeSceneDO) > 0;
    }

    @Override
    public InterlaceNoticeSceneVO noticeSceneDetail(Long id) {
        return interlaceNoticeSceneMapper.selectVoById(id);
    }

    @Override
    public List<InterlaceNoticeSceneVO> noticeSceneList() {
        LambdaQueryWrapper<InterlaceNoticeSceneDO> lqw = new LambdaQueryWrapper<InterlaceNoticeSceneDO>();
        lqw.eq(InterlaceNoticeSceneDO::getDel, "0");
        lqw.orderByDesc(InterlaceNoticeSceneDO::getCreateTime);
        return interlaceNoticeSceneMapper.selectVoList(lqw);
    }

    @Async
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addNotice(NoticeBO bo) {
        InterlaceNoticeSceneDO noticeSceneDO = interlaceNoticeSceneMapper.selectOne(new LambdaQueryWrapper<InterlaceNoticeSceneDO>()
            .eq(InterlaceNoticeSceneDO::getType, bo.getSceneType())
            .last("limit 1"));
        if (noticeSceneDO == null) {
            throw new ServiceException("通知场景不存在");
        }
        if ("customer".equals(bo.getNtfObjRange())) {
            pushService.push(bo, bo.getMemberList());
        } else {
            List<InterlaceMemberDO> memberList = interlaceMemberMapper.selectList(new LambdaQueryWrapper<InterlaceMemberDO>()
                .eq(InterlaceMemberDO::getStatus, "0"));
            if (memberList != null && memberList.size() > 0) {
                List<Long> memberIds = memberList.stream()
                    .map(InterlaceMemberDO::getId)
                    .collect(Collectors.toList());
                pushService.push(bo, memberIds);
            }
        }
    }

    @Override
    public TableDataInfo<CustomNoticeMemberVO> noticeMemberPageList(CustomNoticeMemberParams customNoticeMemberParams, PageQuery pageQuery) {
        QueryWrapper<Object> wrapper = Wrappers.query();
        wrapper.eq("tinm.nid", customNoticeMemberParams.getNid());
        wrapper.eq(StringUtils.isNotBlank(customNoticeMemberParams.getIsRead()), "tinm.is_read", customNoticeMemberParams.getIsRead());
        wrapper.like(StringUtils.isNotBlank(customNoticeMemberParams.getEmail()), "tim.email", customNoticeMemberParams.getEmail());
        wrapper.like(StringUtils.isNotBlank(customNoticeMemberParams.getNickname()), "tim.nickname", customNoticeMemberParams.getNickname());
        wrapper.orderByAsc("tinm.create_time");
        Page<CustomNoticeMemberVO> result = interlaceNoticeMemberMapper.selectPageList(pageQuery.build(), wrapper);
        return TableDataInfo.build(result);
    }

    @Override
    public TableDataInfo<ApiCustomNoticeVO> apiPageList(PageQuery pageQuery) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("当前用户退出登录!");
        }
        Page<ApiCustomNoticeVO> result = interlaceNoticeMemberMapper.apiSelectPageList(pageQuery.build(), loginUser.getUserId());
        return TableDataInfo.build(result);
    }

    @Override
    public ApiCustomNoticeVO apiGetNoticeInfoById(Long id) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("当前用户退出登录!");
        }
        return interlaceNoticeMemberMapper.apiGetNoticeInfoById(id, loginUser.getUserId());
    }

    @Override
    public boolean noticeRead(Long[] ids) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("当前用户退出登录!");
        }
        List<Long> idList = Arrays.asList(ids);
        return interlaceNoticeMemberMapper.update(null, new LambdaUpdateWrapper<InterlaceNoticeMemberDO>()
            .set(InterlaceNoticeMemberDO::getIsRead, "1")
            .eq(InterlaceNoticeMemberDO::getUid, loginUser.getUserId()).in(InterlaceNoticeMemberDO::getNid, idList)) > 0;
    }

    @Override
    public void addNotice(Long sceneId, String mainContent, String subContent, Long uid) {

    }

    @Override
    public List<ApiCustomNoticeVO> apiList() {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("当前用户退出登录!");
        }
        return interlaceNoticeMapper.selectNoticeList(loginUser.getUserId());
    }
}
